package org.robotlegs.base
{
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	
	import org.robotlegs.core.IEventMap;

	
	
public class EventMap implements IEventMap
{
	public function EventMap(eventDispatcher:IEventDispatcher)
	{
		listeners = new Array();
		this.eventDispatcher = eventDispatcher;
	}
	

	protected var eventDispatcher:IEventDispatcher;
	
	protected var _dispatcherListeningEnabled:Boolean = true;
	
	protected var listeners:Array;

	
	
	
	public function get dispatcherListeningEnabled():Boolean{return _dispatcherListeningEnabled;}
	public function set dispatcherListeningEnabled(value:Boolean):void{	_dispatcherListeningEnabled = value;}

	
	
	public function mapListener(dispatcher:IEventDispatcher, type:String, listener:Function, eventClass:Class = null, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = true):void
	{
		if (dispatcherListeningEnabled == false && dispatcher == eventDispatcher)
		{
			throw new ContextError(ContextError.E_EVENTMAP_NOSNOOPING);
		}
		eventClass ||= Event;
		
		var params:Object;
		var i:int = listeners.length;
		while (i--)
		{
			params = listeners[i];
			if (params.dispatcher == dispatcher
				&& params.type == type
				&& params.listener == listener
				&& params.useCapture == useCapture
				&& params.eventClass == eventClass)
			{
				return;
			}
		}
		
		var callback:Function = function(event:Event):void
			{
				routeEventToListener(event, listener, eventClass);
			};
		params = {
				dispatcher: dispatcher,
				type: type,
				listener: listener,
				eventClass: eventClass,
				callback: callback,
				useCapture: useCapture
			};
		listeners.push(params);
		dispatcher.addEventListener(type, callback, useCapture, priority, useWeakReference);
	}
	
	
	public function unmapListener(dispatcher:IEventDispatcher, type:String, listener:Function, eventClass:Class = null, useCapture:Boolean = false):void
	{
		eventClass ||= Event;
		var params:Object;
		var i:int = listeners.length;
		while (i--)
		{
			params = listeners[i];
			if (params.dispatcher == dispatcher
				&& params.type == type
				&& params.listener == listener
				&& params.useCapture == useCapture
				&& params.eventClass == eventClass)
			{
				dispatcher.removeEventListener(type, params.callback, useCapture);
				listeners.splice(i, 1);
				return;
			}
		}
	}
	

	public function unmapListeners():void
	{
		var params:Object;
		var dispatcher:IEventDispatcher;
		while (params = listeners.pop())
		{
			dispatcher = params.dispatcher;
			dispatcher.removeEventListener(params.type, params.callback, params.useCapture);
		}
	}
	

	protected function routeEventToListener(event:Event, listener:Function, originalEventClass:Class):void
	{
		if (event is originalEventClass)
		{
			listener(event);
		}
	}
}
}
